# -*- coding: UTF-8 -*-
# 基于AoI稳定匹配 多源-多卖家
import copy
import random
import AoI_SP
from seller_SP import SellerAoISP
from buyer_SP import BuyerAoISP
from util import Util

import pickle


def match_AoISP(T, s, b):
    """
    使用AoISP算法进行匹配
    arg1:T 时间范围
    arg2:s 数据源集合
    arg3:b 买家集合
    return: pdata 包含x,sellerProfit,buyerUtility
    """
    util = Util()  # 工具类
    pdata = util.initPlotData_SP('match')  # 绘图数据
    # 迭代匹配
    k = 1  # 迭代次数
    while (util.sthChanged(s)):
        # 清除买家收到的报价w
        for i in range(len(b)):
            b[i].w = []
        # 每个数据源先进行活动
        for i in range(len(s)):
            # 数据源寻找所有报价高于成本的买家
            s[i].findBuyerSet(b)
            # 向他们提供报价
            if (len(s[i].w) != 0):
                for ti in s[i].w:
                    b[ti].w.append(i)

        # 每个买家从报价单中进行选择
        for i in range(len(b)):
            b[i].w = AoI_SP.chooseSeller_AoI(s, i, b[i].budget, T)

        # 每个数据源根据结果调整价格
        for i in range(len(s)):
            # 根据是否被拒绝调整价格
            oldprice = s[i].price.copy()  # 要用浅复制
            for ti in s[i].w:
                if (util.isRejected(i, b[ti])):
                    s[i].adjustPrice(ti)
            # 如果价格变化，标志位置1
            if(oldprice == s[i].price):
                s[i].flag = False
            else:
                s[i].flag = True
            # 清空报价列表，以便紧接着更新
            s[i].w = []

        # 更新数据源的被接受列表
        for i in range(len(b)):
            if(len(b[i].w) != 0):
                for si in b[i].w:
                    s[si].w.append(ti)

        # 记录数据
        util.checkPoint_SP(k, s, b, pdata)
        k += 1

    bw = []  # 各个买家选择结果集合
    baoi = []
    for buyer in b:
        bw.append(buyer.w)
        baoi.append(AoI_SP.getAoI(s, buyer.w, T))
    return pdata, bw, baoi


if(__name__ == "__main__"):
    # 参数
    qseller = 25  # 卖家数量
    qbuyer = 3  # 买家数量
    budget = 80  # 初始预算
    T = 100  # 时间段数量
    mode = 'w'  # 数据存取模式

    # 初始化
    s = []  # 卖家集合
    b = []  # 买家集合
    util = Util()
    for i in range(qseller):
        seller = SellerAoISP(i, qbuyer, T)
        s.append(seller)
    for i in range(qbuyer):
        # 随机生成预算
        buyer = BuyerAoISP(i, T, random.randint(budget-10, budget+10))
        b.append(buyer)

    if(mode == 'w'):
        f1 = open('./mydata/sellerdata.pkl', 'wb')
        f2 = open('./mydata/buyerdata.pkl', 'wb')
        pickle.dump(s, f1)
        pickle.dump(b, f2)
    else:
        f1 = open('./mydata/sellerdata.pkl', 'rb')
        f2 = open('./mydata/buyerdata.pkl', 'rb')
        s = pickle.load(f1)
        t = pickle.load(f2)

    pdata, bw, baoi = match_AoISP(T, s, b)
    print(len(pdata['x']))
    print(bw)
    util.doPlot_SP(pdata)
